/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package idea.sfo.viewer.designer;


import idea.sfo.viewer.graphics.TextContent;
import designersfo.Cons;
import designersfo.Cons.CellInfo;
import designersfo.Cons.CellInfo.CellFormat;
import designersfo.Cons.CellInfo.CustomContentCellData;
import idea.model.dbmanager.SfoDbManager;
import idea.sfo.viewer.Canvas;
import idea.sfo.viewer.graphics.CellBorder;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.NoSuchElementException;


/**
 *
 * @author renke002
 */
public class DesignerCol extends DesignerGraphic
{

    /**
     *
     */
    private final static int FIRST_ELEMENT = 0;
    /**
     *
     */
    private Cons cons;
    /**
     *
     */
    private Integer colNumber;
    /**
     *
     */
    private Integer rowNumber;
    /**
     *
     */
    private Long cellHeight;
    /**
     *
     */
    private Long cellWidth;
    /**
     *
     */
    private CellBorder border;
    /**
     * Text label to display.
     */
    private TextContent label;


    /**
     *
     * @param cons
     * @param colNum
     * @param rowNum
     * @param myHeight
     * @param prevRowHeights
     * @param myWidth
     * @param prevColWidths
     */
    public DesignerCol( Cons cons , Integer colNum , Integer rowNum , Long myHeight , Long prevRowHeights , Long myWidth , Long prevColWidths )
    {
        super( rowNum , colNum , myWidth , myHeight , prevColWidths , prevRowHeights );

        this.cons = cons;
        this.colNumber = colNum;
        this.rowNumber = rowNum;
        this.cellHeight = myHeight;
        this.cellWidth = myWidth;

        this.initComponents( prevColWidths , prevRowHeights );
    }


    /**
     * Returns 'true' if this element contains Cell-Data.
     *
     * @return
     */
    public boolean containsCellData()
    {
        /*
         * In order to contain Cell-Data, the element must contain a Cell-Info object.
         */
        if ( this.containsCellInfo() )
        {
            if ( this.getCellInfo().getCustomContentCellData().isEmpty() == false )
            {
                // The set of Cell-Data object(s) is not empty, so there is some
                // custom content data associated with this element.
                return true;
            }
        }
        return false;
    }


    /**
     * Return 'true' if this element contains Cell-Format data.
     *
     * @return
     */
    public boolean containsCellFormat()
    {
        /*
         * In order to contain Cell-Format, the element must contain Cell-Info.
         */
        if ( this.containsCellInfo() )
        {
            if ( this.getCellInfo().getCellFormat().isEmpty() == false )
            {
                // The set of Cell-Format object(s) is not empty, so there is some
                // formatting data associated with this element.
                return true;
            }
        }
        return false;
    }


    /**
     * Returns true if this element contains Cell-Info data.
     *
     * If false, then this is either an empty element or, at most, contains
     * row-info that's only useful to determine the height of this row.
     *
     * @return
     */
    public boolean containsCellInfo()
    {
        /*
         * If the set of Cell-Info objects is empty then this element cannot
         * contain one, so return false. 
         */
        return this.cons.getCellInfo().isEmpty() ? false : true;
    }


    /**
     * Draws this object onto the canvas provided by the java.awt.Graphics2D
     * object passed in as parameter.
     *
     * @param g2d
     */
    @Override
    public void draw( Graphics2D g2d )
    {
        //super.draw( g2d );

        if ( this.border != null )
        {
            this.border.draw( g2d );
        }

        if ( this.label != null )
        {
            g2d.setColor( Color.BLACK );

            // turn ON font AntiAliasing (aka ClearType in Windows) to improve the
            // font readability.
            g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING ,
                    RenderingHints.VALUE_ANTIALIAS_ON );
            g2d.setRenderingHint( RenderingHints.KEY_RENDERING ,
                    RenderingHints.VALUE_RENDER_QUALITY );

            int textX = this.container.x + 3;
            int textY = this.container.y + this.container.height - 3;

            g2d.drawString( this.label.getCharIter() , textX , textY );
        }
    }


    /**
     *
     * @param content_id
     * @param relative_index
     * @return
     */
    private String findCellDataContent( String content_id , String relative_index )
    {
        /*
         * gids-designer:custom-content-cell-data
         * 
         When opening a question layout in the custom layout designer, the first
         stage involves gathering up all of the bits and pieces of content from
         the QUESTION_TITLE, CUSTOM_CONTENT_ITEMS and CUSTOM_RESPONSES tables.
         * 
         Next, the content-id for each cell in the layout is matched to the IDs
         gathered in the previous step. So, for example, if the content-id
         matches a CUSTOM_CONTENT_ITEMS.ITEM_ID, and the relative-index is 4,
         then we know that this cell contains a reference to the ITEM_WORDING for
         that item, and so on.
         * 
         Labels, headers and reusable blocks work exactly the same way.
         Pagemaster templates and regions work similarly, but the content is
         looked up in different places. 
         * 
         *         
         content-id                 relative-index          interpretation
         *
         QUESTION_TITLE.QUEST_ID
         0 reference to a header or reusable block in its entirety 
         2 QUESTION_TITLE.TITLE 
         4 QUESTION_TITLE.QUEST_WORDING 
         7 question number (replaceable token, not explicitly present in content)
         * 
         CUSTOM_CONTENT_ITEMS.ITEM_ID
         3 CUSTOM_CONTENT_ITEMS.ITEM_NUMBER 
         4 CUSTOM_CONTENT_ITEMS.ITEM_WORDING 
         5 CUSTOM_CONTENT_ITEMS.HDR_COLUMN_REF 
         6 CUSTOM_CONTENT_ITEMS.HDR_KEYCODE
         * 
         CUSTOM_RESPONSES.RESPONSES_ID
         1 reference to the response area itself 
         4 CUSTOM_RESPONSES.RESPONSE_LABEL 
         + CUSTOM_RESPONSES.RESPONSE_INSTRUCTION (concatenated) 
         6 CUSTOM_RESPONSES.KEYCODE
         * 
         REGION_DEFINITIONS.REGION_DEF_ID
         8 reference to computed page/face barcode (ACS/Decennial only) 
         9 reference to computed page/face page number (ACS/Decennial only)
         * 
         */
        // get DB connection        
        // find stuff.
        String content = SfoDbManager.findCellDataContent( content_id , relative_index );
        return content;
    }


    /**
     *
     * @return
     */
    public CustomContentCellData getCellData()
    {
        CustomContentCellData cd = null;
        if ( this.containsCellData() )
        {
            cd = this.getCellInfo().getCustomContentCellData().get( FIRST_ELEMENT );
        }
        return cd;
    }


    /**
     *
     * @return
     */
    public CellFormat getCellFormat()
    {
        CellFormat cf = null;
        if ( this.containsCellFormat() )
        {
            cf = this.getCellInfo().getCellFormat().get( FIRST_ELEMENT );
        }
        return cf;
    }


    /**
     *
     * @return
     */
    private CellInfo getCellInfo()
    {
        CellInfo ci = null;
        if ( this.containsCellInfo() )
        {
            ci = this.cons.getCellInfo().get( FIRST_ELEMENT );
        }
        return ci;
    }


    /**
     *
     * @return
     */
    public Integer getColNumber()
    {
        return this.colNumber;
    }


    /**
     *
     * @return
     */
    public long getHeight()
    {
        return this.cellHeight;
    }


    /**
     *
     * @return
     */
    public String getJoinedHoriz()
    {
        return ( this.border.isJoinedHoriz() ) ? "Yes" : "No";
    }


    /**
     *
     * @return
     */
    public String getJoinedVert()
    {
        return ( this.border.isJoinedVert() ) ? "Yes" : "No";
    }


    /**
     *
     * @return
     */
    public String getLabel()
    {
        return ( this.label == null ) ? null : this.label.getLabel();
    }


    /**
     *
     * @return
     */
    public String getName()
    {
        return "Col: " + this.colNumber;
    }


    /**
     *
     * @return
     */
    public String getPosHoriz()
    {
        return ( this.border.getJoinedHorizIndex() + 1 ) + " / " + this.border.getJoinedHorizCount();
    }


    /**
     *
     * @return
     */
    public String getPosVert()
    {
        return ( this.border.getJoinedVertIndex() + 1 ) + " / " + this.border.getJoinedVertCount();
    }


    /**
     *
     * @return
     */
    public Integer getRowNumber()
    {
        return this.rowNumber;
    }


    /**
     *
     * @return
     */
    public long getWidth()
    {
        return this.cellWidth;
    }


    /**
     * Catch-all function to initialize the private variables.
     */
    private void initComponents( long topLeftX , long topLeftY )
    {
        if ( this.containsCellInfo() )
        {
            /* initialize cell-info variables.
             * 
             * Attributes :
             *  joined-cell-count-h :
             *      Integer / required; indicates that this cell is a member of
             *      a group of joined-cell-count-h cells joined in the horizontal
             *      direction 
             *  joined-cell-count-v :
             *      Integer / required; indicates that this cell is a member of 
             *      a group of joined-cell-count-v cells joined in the vertical
             *      direction
             *  joined-cell-index-h :
             *      Integer / required; indicates that this cell is at the 
             *      joined-cell-index-h'th (zero-based) horizontal position in 
             *      the group of which it is a member
             *  joined-cell-index-v :
             *      Integer / required; indicates that this cell is at the 
             *      joined-cell-index-v'th (zero-based) vertical position in the
             *      group of which it is a member 
             */
            CellInfo ci = this.getCellInfo();

            int joinedHorizCellsCount = Integer.parseInt( ci.getJoinedCellCountH() );
            int joinedHorizCellsIndex = Integer.parseInt( ci.getJoinedCellIndexH() );
            int joinedVertCellsCount = Integer.parseInt( ci.getJoinedCellCountV() );
            int joinedVertCellsIndex = Integer.parseInt( ci.getJoinedCellIndexV() );

            this.border = new CellBorder(
                    (int) ( topLeftX / Canvas.FU_SCALE_FACTOR ) , // top left X coord
                    (int) ( topLeftY / Canvas.FU_SCALE_FACTOR ) , // top left Y coord
                    (int) ( this.cellWidth / Canvas.FU_SCALE_FACTOR ) , // width of this cell
                    (int) ( this.cellHeight / Canvas.FU_SCALE_FACTOR ) ,// height of this cell
                    joinedHorizCellsCount , // number of joined horiz cells
                    joinedHorizCellsIndex , // position among the horiz cells
                    joinedVertCellsCount , // number of joined vertical cells
                    joinedVertCellsIndex ); // position among the vertical cells
        }
        if ( this.containsCellData() )
        {
            /* If there's cell data there might also be text.
             */
            try
            {
                this.label = new TextContent( this.findCellDataContent( this.getCellData().getContentId() , this.getCellData().getRelativeIndex() ) );
            }
            catch ( NoSuchElementException nse )
            {
                //Nope, Chuck Testa!
                this.label = null;
                System.err.println( nse );
            }
        }
        else
        {
            this.label = null;
        }
    }


    /**
     *
     * @return
     */
    public boolean isJoinedHoriz()
    {
        return ( this.border.isJoinedHoriz() ) ? true : false;
    }


    /**
     *
     * @return
     */
    public boolean isJoinedVert()
    {
        return ( this.border.isJoinedVert() ) ? true : false;
    }


    /**
     * Set this element's border to be visible.
     *
     * @param visible
     */
    @Override
    public void setBorderVisible( boolean visible )
    {
        this.border.setVisible( visible );
    }


    /**
     *
     * @param label the new label.
     */
    public void setLabel( String label )
    {
        // add formatting function and save it so it isn't recalculated each time
        // in the draw() function.
        this.label.setText( label );
    }


    /**
     *
     * @return
     */
    public void setName( String newName )
    {
        // TO-DO: replace this with useful code.
        this.cons.getCellInfo().get( 0 ).getCellFormat().get( 0 ).setFontFamily( newName );
        System.out.println( "You entered " + this.cons.getCellInfo().get( 0 ).getCellFormat().get( 0 ).getFontFamily() );
    }


    /**
     *
     * @param selected
     */
    @Override
    public void setSelected( boolean selected )
    {
        //super.setSelected( selected );
        this.border.setSelected( selected );
    }

}
